package com.cicoding.uhfreader;


import com.cicoding.config.WebSocket;
import com.cicoding.config.ZebraUHFProperties;
import com.cicoding.domian.KufangData;
import com.cicoding.utlis.JdbcUtils;
import com.cicoding.utlis.NestedCacheExample;
import com.cicoding.utlis.RFIDCacheExample;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import com.uhf.alm.CabinetAlgorithm;
import com.uhf.api.cls.*;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;



@Slf4j
@Component
public class ReaderAsyncReadData {

    @Resource
    private ZebraUHFProperties zebraUHFProperties;

    private ScheduledExecutorService scheduledExecutorService;
    /**
     * 读写次数
     */
    private Map<String, Integer> redNumMap = new HashMap<>();

    private ConcurrentHashMap<String, Integer> ipJL = new ConcurrentHashMap<>();


    @Resource
    private WebSocket webSocket;

    private  Map<String, Long> gpis = new ConcurrentHashMap<>();

    /**
     * 初始化数据,之后的数据用来对比
     */
    private Cache<String, Long> cache  = CacheBuilder.newBuilder()
            .maximumSize(8000) // 可以根据需求设置缓存大小限制，比如1000条记录
            .build();
    /**
     * 盘点到的标签
     */
    Cache<String, Long>  RFIDCache = CacheBuilder.newBuilder()
            .expireAfterWrite(3000, TimeUnit.MINUTES)
            .build();
    /**
     * 数据库数据
     */
    Cache<String, String>  sqlData = CacheBuilder.newBuilder()
            .build();

    ExecutorService exeTest = Executors.newFixedThreadPool(6); // Create a thread pool with 2 threads


    private ScheduledFuture<?> scheduledTask;


    /**
     * 读写器是否初始化
     */
    private ConcurrentHashMap<String, Reader> readerMap = new ConcurrentHashMap<>();

    private ConcurrentHashMap<String, Reader> ipStatus = new ConcurrentHashMap<>();

    private ConcurrentHashMap<String, ZebraUHFProperties.ZebraUHF> zebra = new ConcurrentHashMap<>();


    private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);



    Reader Jreader;

    CabinetAlgorithm CA;

    @Value("${uhfReadMode.antennaDwellTime}")
    private Integer antennaDwellTime;

    @Value("${uhfReadMode.maximumPower}")
    private Integer maximumPower;

    private boolean flage;

    public boolean openReader() {
        boolean isInit = false;
        scheduledExecutorService = Executors.newScheduledThreadPool(zebraUHFProperties.getConfigs().size());
        for (ZebraUHFProperties.ZebraUHF zebraUHF : zebraUHFProperties.getConfigs()) {
            isInit = initReader(zebraUHF) ? true : isInit;
        }
        return isInit;
    }


    public  void query() throws Exception {
        Connection conn = JdbcUtils.getConnect();
        Statement stat = conn.createStatement();
        ResultSet rs = stat.executeQuery("select * from kufangxinxis");
        List<KufangData> list = new ArrayList<>();
        while (rs.next()) {
            sqlData.put(rs.getString("code"),rs.getString("name"));
        }
        JdbcUtils.close(conn, rs);
       // return list;
    }

 /*   public void checkGpis1() {
        for (Map.Entry<String, Reader> entry : readerMap.entrySet()) {
            String ip = entry.getKey();
            Reader reader = entry.getValue();
            GpiInfo_ST gpist = new GpiInfo_ST();
            Reader.READER_ERR readerErr1 = reader.GetGPIEx(gpist);

            if (readerErr1 == Reader.READER_ERR.MT_OK_ERR) {
                for (int i = 0; i < gpist.gpiCount; i++) {
                    String stats = gpist.gpiStats[i].State+"";
                    if (stats.equals("0")) {
                        ipJL.put(ip+"-"+gpist.gpiStats[i].GpiId,gpist.gpiStats[i].State);

                    }else if (null != ipJL.get(ip+"-"+gpist.gpiStats[i].GpiId)){
                        System.out.println("检测到了-开始执行");
                        stopReadTags();
                        RFIDCache.invalidateAll();
                        scheduleTaskWithDelayAndClose(5);
                       // if (null == ipStatus.get(ip)){
                            //ipStatus.put(ip,reader);

                        //    scheduleTaskWithDelayAndClose(5,zebra.get(ip));

                       // executor.execute(() -> scheduleTaskWithDelayAndClose(5));
                       // }
                        ipJL.remove(ip+"-"+gpist.gpiStats[i].GpiId);
                    }
                }

            } else {
                log.error("读写器[{}]获取GPI状态出错: {}", ip, readerErr1);
            }
        }
    }*/

    public void checkGpis1() {
        for (Map.Entry<String, Reader> entry : readerMap.entrySet()) {
            String ip = entry.getKey();
            Reader reader = entry.getValue();
            GpiInfo_ST gpist = new GpiInfo_ST();
            Reader.READER_ERR readerErr1 = reader.GetGPIEx(gpist);

            if (readerErr1 == Reader.READER_ERR.MT_OK_ERR) {
                for (int i = 0; i < gpist.gpiCount; i++) {
                    String stats = gpist.gpiStats[i].State + "";
                    String key =   "wk-ceshi";

                    if (stats.equals("0")) {
                        // 检查该 GPI 最近是否被触发过
                        if (isTriggeredRecently(key)) {
                            // 如果触发过于频繁，则跳过调度任务
                            continue;
                        }

                        ipJL.put(key, gpist.gpiStats[i].State);
                        // 记录触发时间
                        recordTriggerTime(key);
                    } else if (null != ipJL.get(key)) {
                        System.out.println("检测到了-开始执行");
                        stopReadTags();
                        RFIDCache.invalidateAll();
                        scheduleTaskWithDelayAndClose(5);
                        ipJL.remove(key);
                    }
                }
            } else {
                log.error("读写器[{}]获取GPI状态出错: {}", ip, readerErr1);
            }
        }
    }

    // 用于存储每个键的最后触发时间的映射
    Map<String, Long> lastTriggerTimeMap = new HashMap<>();

    // 记录特定键的触发时间的方法
    private void recordTriggerTime(String key) {
        lastTriggerTimeMap.put(key, System.currentTimeMillis());
    }

    // 检查特定键最近是否被触发（在 1 分钟内）
    private boolean isTriggeredRecently(String key) {
        Long lastTriggerTime = lastTriggerTimeMap.get(key);
        if (lastTriggerTime != null) {
            // 计算自上次触发以来的时间差
            long currentTime = System.currentTimeMillis();
            long elapsedTime = currentTime - lastTriggerTime;
            // 检查时间差是否小于2秒（2000毫秒）
            return elapsedTime < 2000;
        }
        return false; // 如果没有先前的触发，则认为最近未触发
    }



    private boolean initReader(ZebraUHFProperties.ZebraUHF zebraUHF){
        String ip = zebraUHF.getIP();
        Jreader = readerMap.get(ip);
        //根据ip把信息存储起来,检测的时候检测到那个ip的就用那个
        zebra.put(ip,zebraUHF);

        if (Jreader != null) {
            readerMap.remove(ip);
            //startMap.remove(ip);
            Jreader.CloseReader();
        }
        Jreader = new Reader();
        // 创建读写器，传入读写器地址串口或者网口，天线口总个数
        Reader.READER_ERR er = Jreader.InitReader_Notype(zebraUHF.getIP(), zebraUHF.getPortNum());
        if (er != Reader.READER_ERR.MT_OK_ERR){
            log.error("UHF读写器[{}], 连接读写器出错: {}", ip, er);
            return false;
        }

        Jreader.addReadExceptionListener(REL);
        Jreader.addReadListener(RL);

        //获取硬件信息
        Reader.HardwareDetails val = Jreader.new HardwareDetails();
        er = Jreader.GetHardwareDetails(val);
        //获取版本信息
        Reader.ReaderVersion rdrver = Jreader.new ReaderVersion();
        Jreader.ParamGet(Reader.Mtr_Param.MTR_PARAM_READER_VERSION, rdrver);

        log.info("UHF读写器[{}], hardwareVer: {}, softwareVer: {}", ip, rdrver.hardwareVer, rdrver.softwareVer);

        int[] val2 = new int[1];
        er = Jreader.ParamGet(Reader.Mtr_Param.MTR_PARAM_READER_AVAILABLE_ANTPORTS, val2);

        //获取可配置的最大功率，最小功率
        int[] maxpower = new int[1];
        Jreader.ParamGet(Reader.Mtr_Param.MTR_PARAM_RF_MAXPOWER, maxpower);
        int[] minpower = new int[1];
        Jreader.ParamGet(Reader.Mtr_Param.MTR_PARAM_RF_MINPOWER, minpower);
        log.info("UHF读写器[{}], 最大功率: {}, 最小功率: {}", ip,  maxpower[0], minpower[0]);

        //设置最大功率
        Reader.AntPowerConf apcf = Jreader.new AntPowerConf();
        apcf.antcnt = zebraUHF.getPortNum();
        int newMaxPower = 2800; // 假设你想设置的最大功率是2200
        for (int i = 0; i < apcf.antcnt; i++) {
            Reader.AntPower jaap = Jreader.new AntPower();
            jaap.antid = i + 1;
           /* jaap.readPower = (short)maxpower[0];
            jaap.writePower = (short)maxpower[0];*/
            jaap.readPower = (short)newMaxPower;
            jaap.writePower = (short)newMaxPower;
            apcf.Powers[i] = jaap;
        }
        Reader.AntPowerConf apcf2 = Jreader.new AntPowerConf();
        er = Jreader.ParamSet(Reader.Mtr_Param.MTR_PARAM_RF_ANTPOWER, apcf);
        er = Jreader.ParamGet(Reader.Mtr_Param.MTR_PARAM_RF_ANTPOWER, apcf2);
        for (int i = 0; i < apcf2.antcnt; i++) {
            log.info("UHF读写器[{}], 天线端口: {}, 读功率: {}, 写功率: {}", ip, apcf2.Powers[i].antid, apcf2.Powers[i].readPower, apcf2.Powers[i].writePower);
        }

        //设置北美频段
        Reader.Region_Conf rcf1 = Reader.Region_Conf.RG_NA;
        er = Jreader.ParamSet(Reader.Mtr_Param.MTR_PARAM_FREQUENCY_REGION, rcf1);

        //设置gen2协议，可选非必要，现在模块默认为gen2协议
        Reader.Inv_Potls_ST ipst = Jreader.new Inv_Potls_ST();
        ipst.potlcnt = 1;
        ipst.potls = new Reader.Inv_Potl[1];
        for (int i = 0; i < ipst.potlcnt; i++) {
            Reader.Inv_Potl ipl = Jreader.new Inv_Potl();
            ipl.weight = 30;
            ipl.potl = Reader.SL_TagProtocol.SL_TAG_PROTOCOL_GEN2;
            ipst.potls[0] = ipl;
        }
        er = Jreader.ParamSet(Reader.Mtr_Param.MTR_PARAM_TAG_INVPOTL, ipst);

        //设置是否检测天线，如果需要使用不可检测的天线（即无法检测天线是否连接在天线端口上）需要此项设置。
        er = Jreader.ParamSet(Reader.Mtr_Param.MTR_PARAM_READER_IS_CHK_ANT, new int[] { 0 });

        //设置session0  值0，1，2，3   ，0用于少数标签，1用于多标签 ，2和3 不常用，（标签只读一遍，若需持续用需要配合target参数使用）
        er = Jreader.ParamSet(Reader.Mtr_Param.MTR_PARAM_POTL_GEN2_SESSION, new int[] { 0 });

        readerMap.put(ip, Jreader);
        return true;

    }

    public void compareCachesAndPrintMessages() {
        Map<String, Long> cacheData = cache.asMap();
        //Map<String, Long> cacheData = NestedCacheExample.getFromNestedCacheData(IP).asMap();
        Map<String, Long> RFIDCacheData = RFIDCache.asMap();
        //Map<String, Long> RFIDCacheData = RFIDCacheExample.getFromNestedCacheData(IP).asMap();

        Iterator<Map.Entry<String, Long>> cacheIterator = cacheData.entrySet().iterator();
        while (cacheIterator.hasNext()) {
            Map.Entry<String, Long> entry = cacheIterator.next();
            String key = entry.getKey();
            if (!RFIDCacheData.containsKey(key)) {
                if (sqlData.asMap().containsKey(key)) {
                    String value = sqlData.getIfPresent(key);
                    System.out.println(key + " -  (出库) 工器具"+value);
                    webSocket.sendInfo(key + " -  (出库) 工器具"+value,"89");
                    cacheIterator.remove(); // Remove the data from cacheData
                }
            }
        }

        Iterator<Map.Entry<String, Long>> RFIDIterator = RFIDCacheData.entrySet().iterator();
        List<String> keysToAdd = new ArrayList<>();
        while (RFIDIterator.hasNext()) {
            Map.Entry<String, Long> entry = RFIDIterator.next();
            String key = entry.getKey();
            if (!cacheData.containsKey(key)) {
                if (sqlData.asMap().containsKey(key)) {
                    keysToAdd.add(key);
                    String value = sqlData.getIfPresent(key);
                    webSocket.sendInfo(key + " -  (入库) 工器具"+value,"89");
                    System.out.println(key + " -  (入库) 工器具"+value);
                }
            }
        }
        // System.out.println();

        String cache = "";

        for (Map.Entry<String, Long> entry : cacheData.entrySet()) {
            cache += entry.getKey() +" , ";
           // System.out.println("Tag: " + entry.getKey() + ", Value: " + entry.getValue());
        }
        String rfid = "";

        for (Map.Entry<String, Long> entry : RFIDCacheData.entrySet()) {
            rfid += entry.getKey() + " , ";
            //System.out.println("Tag: " + entry.getKey() + ", Value: " + entry.getValue());
        }

        System.out.println("\nRFID Cache Data: "+ cache);
        System.out.println("\nRFID rfid Data: "+ rfid);

        log.error("\nRFID Cache Data: {}", cache);
        log.error("RFID rfid Data: {}",rfid);
        // Add the new keys to cacheData
        for (String key : keysToAdd) {
            cacheData.put(key, System.currentTimeMillis());
        }
        try {
        //    webSocket.sendInfo("3333","89");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        RFIDCache.invalidateAll();
    }


    private boolean startReader(ZebraUHFProperties.ZebraUHF zebraUHF) {
        String ip = zebraUHF.getIP();

        Reader Jreader = readerMap.get(ip);
        ipStatus.put(ip,Jreader);
        if (Jreader == null) {
            return false;
        }
        Reader.CustomParam_ST cpst = Jreader.new CustomParam_ST();
        cpst.ParamName="Reader/Ex10fastmode";
        byte[] vals=new byte[22];
        vals[0]=1;//注意 vals[0]=1 。
        vals[1]=20;
        for(int i=0;i<20;i++)
            vals[2+i]=(byte)i;
        cpst.ParamVal=vals;
        Jreader.ParamSet(Reader.Mtr_Param.MTR_PARAM_CUSTOM, cpst);

        //初始化结BackReadOption
        BackReadOption m_BROption=new BackReadOption();
        //本例只使用天线1进行盘存，如果要使用多个天线则只需要将使用的天线编
        //号赋值到数组ants中，例如同时使用天线1和2，则代码应该改为ants[0] = 1;ants[1] = 2;antcnt = 2;
        log.info("[zebraUHF]读写器IP: {}, 端口数: {}, 天线组: {}", zebraUHF.getIP(), zebraUHF.getPortNum(), zebraUHF.getAntArray());
        String[] antsStr = zebraUHF.getAntArray().split(",");
        int antcnt = antsStr.length;
        int[] ants = new int[antcnt];
        for(int i = 0; i < antcnt; i++){
            if(StringUtils.isNotBlank(antsStr[i])){
                ants[i] = Integer.parseInt(antsStr[i]);
            }
        }
        /*是否采用高速模式（目前只有slr11xx和slr12xx系列读写器才支持）,对于
         *一般标签数量不大，速度不快的应用没有必要使用高速模式,本例没有设置
         *使用高速模式
         * */
        m_BROption.IsFastRead = true;//true 表示快速模式/高速模式,false 表示普通模式


        ///非高速盘存模式下必须要设置的参数*******************************************
        //盘存周期,单位为ms，可根据实际使用的天线个数按照每个天线需要200ms
        //的方式计算得出,如果启用高速模式则此选项没有任何意义，可以设置为
        //任意值，或者干脆不设置
        m_BROption.ReadDuration = (short)(200 * antcnt);
        //盘存周期间的设备不工作时间,单位为ms,一般可设置为0，增加设备不工作
        //时间有利于节电和减少设备发热（针对某些使用电池供电或空间结构不利
        //于散热的情况会有帮助）
        m_BROption.ReadInterval = 0;
        //****************************************************************************


        //高速盘存模式参数设置********************************************************
        //以下为选择使用高速模式才起作用的选项参,照如下设置即可,如果使能高速
        //模式，即把IsFastRead设置为true则,只需取消以下被注释的代码即可
        //*
        //高速模式下为取得最佳效果设置为0即可
        m_BROption.FastReadDutyRation = 0;
        //标签信息是否携带识别天线的编号
        m_BROption.TMFlags.IsAntennaID = true;
        //标签信息是否携带标签识别次数
        //m_BROption.TMFlags.IsReadCnt = false;
        m_BROption.TMFlags.IsReadCnt = true;
        //标签信息是否携带识别标签时的信号强度
        m_BROption.TMFlags.IsRSSI = false;
        //标签信息是否携带时间戳
        m_BROption.TMFlags.IsTimestamp = false;
        //标签信息是否携带识别标签时的工作频点
        m_BROption.TMFlags.IsFrequency = false;
        //标签信息是否携带识别标签时同时读取的其它bank数据信息,如果要获取在
        //盘存时同时读取其它bank的信息还必须设置MTR_PARAM_TAG_EMBEDEDDATA参数,
        //（目前只有slr11xx和slr12xx系列读写器才支持）
        m_BROption.TMFlags.IsEmdData = false;
        //保留字段，可始终设置为0
        m_BROption.TMFlags.IsRFU = false;
        //*/
        Reader.READER_ERR er = Jreader.StartReading(ants, antcnt, m_BROption);
   /*     if (er != Reader.READER_ERR.MT_OK_ERR){
            log.error("UHF读写器[{}], 以事件启动读标签出错: {}", ip, er);
            return false;
        }*/
      //  startMap.put(ip, true);
        return true;
    }

    /**
     * 标签监听
     */
    ReadListener RL = new ReadListener() {
        @Override
        public void tagRead(Reader r, final Reader.TAGINFO[] tag) {
            // TODO Auto-generated method stub
            Vector<String> code1 = new Vector<String>();
            for (Reader.TAGINFO taginfo : tag) {
                String code = Reader.bytes_Hexstr(taginfo.EpcId);
               // checkGpi();
                SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
                //concurrentHashMap.put(code, dateFormat1.format(new Date()));
               // hashMaps.put(r.GetReaderAddress(), concurrentHashMap);
                long timeMillis = System.currentTimeMillis();
                if(flage){
                    cache.put(code, timeMillis);
                    //根据ip来区分
                    // NestedCacheExample.putToNestedCache(r.GetReaderAddress(),code,timeMillis);
                    log.error("--首轮打印标签---- {} ip是多少 {} ",code,r.GetReaderAddress());
                }else{
                    RFIDCache.put(code,timeMillis);
                    log.error("--触发打印---- {} ip是多少 {} ",code,r.GetReaderAddress());
                    // RFIDCacheExample.putToNestedCache(r.GetReaderAddress(),code,timeMillis);
                }



                //log.error("这个是什么呢 {} ",code);
                //  code1.add(code);
                //concurrentHashMap.put(r.GetReaderAddress(),code1);
               // handleTags.handleTag(code);
            }
        }
    };


    ReadExceptionListener REL = (r, re) -> {
        String address =  r.GetReaderAddress();
        //如果需要可在此处记录异常日志
        log.error("[zebraUHF]读写器[{}]异常信息: {} ", address, re);
        //判断是否异常发生过于频繁
        /*if (rechecker.IsTrigger()) {
            log.error("[zebraUHF]读写器[{}]异常太过频繁,错误信息: {}", address, re);
            return;
        } else {
            rechecker.AddErr();
        }*/
        if(Reader.READER_ERR.MT_CMD_FAILED_ERR == re || Reader.READER_ERR.MT_CMD_NO_TAG_ERR == re){
            return;
        }

        ZebraUHFProperties.ZebraUHF readerZebraUHF = null;
        for(ZebraUHFProperties.ZebraUHF zebraUHF : zebraUHFProperties.getConfigs()){
            if(address.equals(zebraUHF.getIP())){
                readerZebraUHF = zebraUHF;
            }
        }
        if(readerZebraUHF == null){
            return;
        }
        //尝试重新连接读写器并启动盘存操作
        boolean reConnect = false;

        while(!reConnect) {
            log.info("ReadExceptionListener [zebraUHF]读写器[{}]正在进行重连......", address);
            if (initReader(readerZebraUHF)) {
                log.info("ReadExceptionListener [zebraUHF]读写器[{}]重连成功......", address);
                // 判断是否开启读标签
              /*  if(InventoryRecordDetailService.isStartScan()){
                    if (startReader(readerZebraUHF)) {
                        log.info("ReadExceptionListener [zebraUHF]读写器[{}]开启读取标签成功......",address);
                        reConnect = true;
                    }
                }else{
                    reConnect = true;
                }*/
            }
            if (!reConnect) {
                log.error("[zebraUHF]读写器[{}]重连失败, 5s后重新连接! ", address);
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    log.error(e.getMessage());
                }
            }
        }
    };


    public boolean stopReadTags() {
        System.out.println("结束盘点");
        webSocket.sendInfo("结束盘点","89");
        for (String ip : readerMap.keySet()) {
            Reader rdr = readerMap.get(ip);
            if (null != rdr) {
                rdr.StopReading();
            }
            ipStatus.remove(ip);
        }
        //startMap.clear();
        return true;
    }

    public boolean stopReadTagss(ZebraUHFProperties.ZebraUHF zebraUHF) {
        System.out.println("结束判断的ip-----------"+ zebraUHF.getIP());
        webSocket.sendInfo("结束盘点","89");
        Reader rdr = readerMap.get(zebraUHF.getIP());
        ipStatus.remove(zebraUHF.getIP());
        //停止
        rdr.AsyncStopReading_IT();
        //startMap.clear();
        return true;
    }




    private ScheduledFuture<?> previousTaskFuture; // 用于存储上一个任务的引用

   /* public void scheduleTaskWithDelayAndClose(int delayInSeconds) {

        flage = false;
        scheduledTask =  executor.schedule(() -> {
            try {
                // 在延迟之前执行关闭方法
               // System.out.println("执行关闭其他方法...");
                webSocket.sendInfo("开始盘点","89");
                //startReader(zebraUHF);
                for (ZebraUHFProperties.ZebraUHF zebraUHF : zebraUHFProperties.getConfigs()) {
                    startReader(zebraUHF);
                    Thread.sleep(100); // 每秒钟检查一次
                }

                // 延迟指定秒数后执行任务
                executor.schedule(() -> {
                    // 执行需要延迟执行的任务
                    compareCachesAndPrintMessages();
                  //  System.out.println("执行延迟任务...");

                    stopReadTags();
                }, delayInSeconds, TimeUnit.SECONDS);
            } catch (Exception e) {
                // 处理异常
                e.printStackTrace();
            }
        }, 0, TimeUnit.SECONDS);
    }*/

    private boolean isFirstExecution = true; // 添加标志以判断是否是第一次执行
    private boolean isTaskScheduled = false; // 添加标志以判断任务是否已经被调度

    /**
     * 当执行这个定时任务时，如果在倒计时期间再次被调用，会取消之前的定时任务。
     * 在取消之前的任务后，重新计划一个新的任务。
     * 在延迟之前执行一些操作，比如记录日志和发送 WebSocket 信息。
     * 在延迟期间执行一些其他操作，比如通过 startReader 方法启动读取器。
     * 在延迟结束后执行具体的延迟任务，如果 isFirstExecution 为 false，则执行额外的比较任务等。
     * 如果在倒计时期间再次调用这个方法，会取消之前的定时任务，并且只有当倒计时结束之后，才会执行 isFirstExecution 里面的方法。
     * @param delayInSeconds
     */

    public void scheduleTaskWithDelayAndClose(int delayInSeconds) {
        flage = false;
        if (isTaskScheduled) {
            // 如果任务已经被调度，取消之前的任务并重新计时延迟
            scheduledTask.cancel(true);
        }

        scheduledTask = executor.schedule(() -> {
            try {
                // 在延迟之前执行关闭方法
                // System.out.println("执行关闭其他方法...");
                log.error("--------------开始盘点 ---------");
                webSocket.sendInfo("开始盘点", "89");

                //startReader(zebraUHF);
                for (ZebraUHFProperties.ZebraUHF zebraUHF : zebraUHFProperties.getConfigs()) {
                    startReader(zebraUHF);
                    try {
                        // 执行任务代码
                        Thread.sleep(100); // 每秒钟检查一次
                    } catch (InterruptedException e) {
                        // 处理中断异常
                        Thread.currentThread().interrupt(); // 清除中断状态
                    }
                }

                // 延迟指定秒数后执行任务
                scheduledTask = executor.schedule(() -> {
                    // 执行需要延迟执行的任务
                    if (!isFirstExecution) { // 如果不是第一次执行，则执行比较任务
                        compareCachesAndPrintMessages();
                        stopReadTags();
                    }
                    //  System.out.println("执行延迟任务...");

                }, delayInSeconds, TimeUnit.SECONDS);

                isFirstExecution = false; // 标记为不是第一次执行
                isTaskScheduled = true; // 标记任务已经被调度
            } catch (Exception e) {
                // 处理异常
                e.printStackTrace();
            }
        }, 0, TimeUnit.SECONDS);
    }


    /*public void scheduleTaskWithDelayAndClose(int delayInSeconds, ZebraUHFProperties.ZebraUHF zebraUHF) {
        // 将任务封装为Runnable对象
        Runnable task = () -> {
            try {
                // 调用方法开始盘点
                webSocket.sendInfo("开始盘点", "89");
                startReader(zebraUHF);

                // 延迟指定秒数后执行盘点结束任务
                executor.schedule(() -> {
                    try {
                        compareCachesAndPrintMessages(zebraUHF.getIP());
                        stopReadTagss(zebraUHF);
                    } catch (Exception e) {
                        log.error("盘点结束任务执行出错", e);
                    }
                }, delayInSeconds, TimeUnit.SECONDS);
            } catch (Exception e) {
                log.error("盘点开始任务执行出错", e);
            }
        };

        // 将封装好的任务提交到线程池执行
        executor.schedule(task, 0, TimeUnit.SECONDS);
    }*/

    public void scheduleTaskWithDelay(int delayInSeconds) {
        flage = true;
        executor.schedule(() -> {
            try {
                // 在延迟之前执行关闭方法
                // System.out.println("执行关闭其他方法...");
                //初始化的时候,如果有两个读写器需要都运行盘点
                //startReader(zebraUHFProperties.getConfigs().get(0));
                for (ZebraUHFProperties.ZebraUHF zebraUHF : zebraUHFProperties.getConfigs()) {
                    startReader(zebraUHF);
                }
                executor.schedule(() -> {
                    // 执行需要延迟执行的任务
                    stopReadTags();
                    //stateData();
                }, delayInSeconds, TimeUnit.SECONDS);
            } catch (Exception e) {
                // 处理异常
                e.printStackTrace();
            }
        }, 0, TimeUnit.SECONDS);
    }

    private void stateData() {

        while (true){
            checkGpis1();
            try {
                Thread.sleep(100); // 每秒钟检查一次
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }


    @PreDestroy
    public void shutdown() {
        if (!executor.isShutdown()) {
            executor.shutdown();
            try {
                if (!executor.awaitTermination(800, TimeUnit.MILLISECONDS)) {
                    executor.shutdownNow();
                }
            } catch (InterruptedException ex) {
                executor.shutdownNow();
            }
        }
    }






}
